﻿namespace Bigway.Common.Models.DtoModels;

using static ErrorResponse;

public static class Errors
{
    public static ErrorDto EntityNotFound(string id, string entityName, string entityUserName) =>
        new()
        {
            Code = ErrorCode.EntityNotFound,
            Message = $"The {entityName} with id {id} is not found.",
            UserMessage = $"{entityUserName} {id} 不存在."
        };

    public static ErrorDto EntityDeleted(string id, string entityName, string entityUserName) =>
        new()
        {
            Code = ErrorCode.EntityDeleted,
            Message = $"The {entityName} {id} is already deleted.",
            UserMessage = $"{entityUserName} {id} 已删除."
        };

    public static ErrorDto SystemNotFound(string systemId) =>
        EntityNotFound(systemId, "system", "系统");

    public static T SystemNotFound<T>(string systemId)
        where T : BaseResponseDto, new() =>
        Create<T>(SystemNotFound(systemId));

    public static ErrorDto InvalidAddress(string address) =>
        new()
        {
            Code = ErrorCode.InvalidAddress,
            Message = $"The address {address} is invalid or too vague.",
            UserMessage = $"地址\"{address}\"无效或不够精确."
        };

    public static T InvalidAddress<T>(string address)
        where T : BaseResponseDto, new() =>
        Create<T>(InvalidAddress(address));

    public static ErrorDto InvalidDateRange() =>
        new()
        {
            Code = ErrorCode.InvalidDateRange,
            Message = "The date range is invalid.",
            UserMessage = "无效日期区间."
        };

    public static T InvalidDateRange<T>()
        where T : BaseResponseDto, new() =>
        Create<T>(InvalidDateRange());

    public static ErrorDto InvalidUser(string userName) =>
        new()
        {
            Code = ErrorCode.InvalidUser,
            Message = $"The user with name {userName} is invalid.",
            UserMessage = $"用户{userName}无效."
        };

    public static T InvalidUser<T>(string userName)
        where T : BaseResponseDto, new() =>
        Create<T>(InvalidUser(userName));

    public static ErrorDto FileNotFound(string id) =>
        EntityNotFound(id, "file", "文件");

    public static T FileNotFound<T>(string id)
        where T : BaseResponseDto, new() =>
        Create<T>(FileNotFound(id));

    public static ErrorDto ProductTypeCodeNotFound(string code) =>
        EntityNotFound(code, "product type code", "产品编号");

    public static T ProductTypeCodeNotFound<T>(string code)
        where T : BaseResponseDto, new() =>
        Create<T>(ProductTypeCodeNotFound(code));

    public static ErrorDto PromotionStatusCodeNotFound(string code) =>
        EntityNotFound(code, "promotion status code", "活动状态");

    public static T PromotionStatusCodeNotFound<T>(string code)
        where T : BaseResponseDto, new() =>
        Create<T>(PromotionStatusCodeNotFound(code));

    public static ErrorDto BenefitsCardNotFound(string benefitsCardId) =>
        EntityNotFound(benefitsCardId, "benefits card", "权益卡");

    public static T BenefitsCardNotFound<T>(string benefitsCardId)
        where T : BaseResponseDto, new() =>
        Create<T>(BenefitsCardNotFound(benefitsCardId));

    public static ErrorDto BenefitsCardDeleted(string benefitsCardId) =>
        EntityDeleted(benefitsCardId, "benefits card", "权益卡");

    public static T BenefitsCardDeleted<T>(string benefitsCardId)
        where T : BaseResponseDto, new() =>
        Create<T>(BenefitsCardDeleted(benefitsCardId));

    public static ErrorDto BackgroundJobNotFound(string jobId) =>
        EntityNotFound(jobId, "background job", "后台任务");

    public static T BackgroundJobNotFound<T>(string jobId)
        where T : BaseResponseDto, new() =>
        Create<T>(BackgroundJobNotFound(jobId));

    #region Business Circle

    public static ErrorDto BusinessCircleNotFound(string businessCircleId) =>
        EntityNotFound(businessCircleId, "business circle", "商圈");

    public static T BusinessCircleNotFound<T>(string businessCircleId)
        where T : BaseResponseDto, new() =>
        Create<T>(BusinessCircleNotFound(businessCircleId));

    public static ErrorDto BusinessCircleDeleted(string businessCircleId) =>
        EntityDeleted(businessCircleId, "business circle", "商圈");

    public static T BusinessCircleDeleted<T>(string businessCircleId)
        where T : BaseResponseDto, new() =>
        Create<T>(BusinessCircleDeleted(businessCircleId));

    public static ErrorDto BusinessCircleHasMerchants(string businessCircleId) =>
        new()
        {
            Code = ErrorCode.BusinessCircleHasMerchants,
            Message = $"The business circle {businessCircleId} is already deleted.",
            UserMessage = $"商圈 {businessCircleId} 已有关联商家."
        };

    public static T BusinessCircleHasMerchants<T>(string businessCircleId)
        where T : BaseResponseDto, new() =>
        Create<T>(BusinessCircleHasMerchants(businessCircleId));

    #endregion

    public static ErrorDto PromotionNotFound(string promotionId) =>
        EntityNotFound(promotionId, "promotion", "活动");

    public static T PromotionNotFound<T>(string promotionId)
        where T : BaseResponseDto, new() =>
        Create<T>(PromotionNotFound(promotionId));

    public static ErrorDto PromotionDeleted(string promotionId) =>
        EntityDeleted(promotionId, "promotion", "活动");

    public static T PromotionDeleted<T>(string promotionId)
        where T : BaseResponseDto, new() =>
        Create<T>(PromotionDeleted(promotionId));

    public static ErrorDto ProductNotFound(string productId) =>
        EntityNotFound(productId, "product", "产品");

    public static T ProductNotFound<T>(string productId)
        where T : BaseResponseDto, new() =>
        Create<T>(ProductNotFound(productId));

    public static ErrorDto CrmebProductNotFound(string productId) =>
        EntityNotFound(productId, "crmeb product", "CRMEB商城产品");

    public static T CrmebProductNotFound<T>(string productId)
        where T : BaseResponseDto, new() =>
        Create<T>(CrmebProductNotFound(productId));

    public static ErrorDto BenefitDeleted(string benefitId) =>
        EntityDeleted(benefitId, "benefit", "权益");

    public static T BenefitDeleted<T>(string benefitId)
        where T : BaseResponseDto, new() =>
        Create<T>(BenefitDeleted(benefitId));

    public static ErrorDto BenefitNotFound(string benefitId) =>
        EntityNotFound(benefitId, "benefit", "权益");

    public static T BenefitNotFound<T>(string benefitId)
        where T : BaseResponseDto, new() =>
        Create<T>(BenefitNotFound(benefitId));

    public static ErrorDto ProductDeleted(string productId) =>
        EntityDeleted(productId, "product", "产品");

    public static T ProductDeleted<T>(string productId)
        where T : BaseResponseDto, new() =>
        Create<T>(ProductDeleted(productId));

    public static ErrorDto VoucherNotFound(string voucher) =>
        EntityNotFound(voucher, "voucher", "权益券");

    public static T VoucherNotFound<T>(string voucher)
        where T : BaseResponseDto, new() =>
        Create<T>(VoucherNotFound(voucher));

    public static ErrorDto VoucherDeleted(string voucherId) =>
        EntityDeleted(voucherId, "voucher", "权益券");

    public static T VoucherDeleted<T>(string voucherId)
        where T : BaseResponseDto, new() =>
        Create<T>(VoucherDeleted(voucherId));

    public static ErrorDto IssuedBenefitsCardNotFound(string issuedBenefitsCardId) =>
        EntityNotFound(issuedBenefitsCardId, "issued benefits card", "核发权益卡");

    public static T IssuedBenefitsCardNotFound<T>(string issuedBenefitsCardId)
        where T : BaseResponseDto, new() =>
        Create<T>(IssuedBenefitsCardNotFound(issuedBenefitsCardId));

    public static ErrorDto IssuedBenefitsCardDeleted(string issuedBenefitsCardId) =>
        EntityDeleted(issuedBenefitsCardId, "issued benefits card", "核发权益卡");

    public static T IssuedBenefitsCardDeleted<T>(string issuedBenefitsCardId)
        where T : BaseResponseDto, new() =>
        Create<T>(IssuedBenefitsCardDeleted(issuedBenefitsCardId));

    public static ErrorDto RefererAccountNotFound(string refererAccount) =>
        EntityNotFound(refererAccount, "referer account", "佣金账户");

    public static T RefererAccountNotFound<T>(string refererAccount)
        where T : BaseResponseDto, new() =>
        Create<T>(RefererAccountNotFound(refererAccount));

    public static ErrorDto RefererAccountDeleted(string refererAccount) =>
        EntityDeleted(refererAccount, "referer account", "佣金账户");

    public static T RefererAccountDeleted<T>(string refererAccount)
        where T : BaseResponseDto, new() =>
        Create<T>(RefererAccountDeleted(refererAccount));

    public static ErrorDto CrmebOrderNotFound(string orderNo) =>
        EntityNotFound(orderNo, "order", "订单");

    public static T CrmebOrderNotFound<T>(string orderNo)
        where T : BaseResponseDto, new() =>
        Create<T>(CrmebOrderNotFound(orderNo));

    public static ErrorDto CrmebOrderDeleted(string orderNo) =>
        EntityDeleted(orderNo, "order", "订单");

    public static T CrmebOrderDeleted<T>(string orderNo)
        where T : BaseResponseDto, new() =>
        Create<T>(CrmebOrderDeleted(orderNo));

    public static ErrorDto RefererFeeBalanceNotEnough(string refererAccount) =>
        new ErrorDto
        {
            Code = ErrorCode.RefererFeeBalanceNotEnough,
            Message = $"The referer account {refererAccount} doesn't have enough balance",
            UserMessage = $"佣金账户{refererAccount}余额不足"
        };

    public static T RefererFeeBalanceNotEnough<T>(string refererAccount)
        where T : BaseResponseDto, new() =>
        Create<T>(RefererFeeBalanceNotEnough(refererAccount));

    public static ErrorDto VoucherAlreadyUsed(string voucherId) =>
        new()
        {
            Code = ErrorCode.VoucherAlreadyUsed,
            Message = $"The voucher with id {voucherId} is already used.",
            UserMessage = $"权益券{voucherId}已使用. 不可再次核销."
        };

    public static T VoucherAlreadyUsed<T>(string voucherId)
        where T : BaseResponseDto, new() =>
        Create<T>(VoucherAlreadyUsed(voucherId));

    public static ErrorDto ConsumeCodeExpired(string code) =>
        new()
        {
            Code = ErrorCode.ConsumeCodeExpired,
            Message = $"The consume code {code} has expired.",
            UserMessage = $"消费码{code}已经过期."
        };

    public static T ConsumeCodeExpired<T>(string code)
        where T : BaseResponseDto, new() =>
        Create<T>(ConsumeCodeExpired(code));

    public static ErrorDto ConsumeCodeNotActiveYet(string code) =>
        new()
        {
            Code = ErrorCode.ConsumeCodeNotActiveYet,
            Message = $"The consume code {code} is not active yet.",
            UserMessage = $"消费码{code}尚未到激活日期."
        };

    public static T ConsumeCodeNotActiveYet<T>(string code)
        where T : BaseResponseDto, new() =>
        Create<T>(ConsumeCodeNotActiveYet(code));

    public static ErrorDto InvalidRequest(string message, string userMessage) =>
        new()
        {
            Code = ErrorCode.InvalidRequest,
            Message = message,
            UserMessage = userMessage
        };

    public static T InvalidRequest<T>(string message, string userMessage)
        where T : BaseResponseDto, new() =>
        Create<T>(InvalidRequest(message, userMessage));

    public static ErrorDto Unauthorized() =>
        new()
        {
            Code = ErrorCode.Unauthorized,
            Message = "The access is unauthorized.",
            UserMessage = "访问未授权."
        };

    public static T Unauthorized<T>()
        where T : BaseResponseDto, new() =>
        Create<T>(Unauthorized());

    public static ErrorDto InternalError() =>
        new()
        {
            Code = ErrorCode.InternalError,
            Message = "Internal server error.",
            UserMessage = "服务器内部错误."
        };

    public static T InternalError<T>()
        where T : BaseResponseDto, new() =>
        Create<T>(InternalError());

    public static ErrorDto InternalError(Exception ex) =>
        new()
        {
            Code = ErrorCode.InternalError,
            Message = $"Unexpected error happened: {ex.Message}.",
            UserMessage = $"服务器发生未知错误: {ex.Message}."
        };

    public static T InternalError<T>(Exception ex)
        where T : BaseResponseDto, new() =>
        Create<T>(InternalError(ex));

    public static ErrorDto UserNameOrPasswordIncorrect() =>
        new()
        {
            Code = ErrorCode.UserNameOrPasswordIncorrect,
            Message = "The user name or the Password is incorrect.",
            UserMessage = "用户名或者密码错误."
        };

    public static T UserNameOrPasswordIncorrect<T>()
        where T : BaseResponseDto, new() =>
        Create<T>(UserNameOrPasswordIncorrect());

    public static ErrorDto SystemNotSupported(string systemId) =>
        new()
        {
            Code = ErrorCode.SystemNotSupported,
            Message = $"The system with id {systemId} is not supported yet. Please contact the developer.",
            UserMessage = $"{systemId}系统尚不被支持, 请联系开发人员."
        };

    public static T SystemNotSupported<T>(string systemId)
        where T : BaseResponseDto, new() =>
        Create<T>(SystemNotSupported(systemId));

    public static ErrorDto InvalidMerchantApply(string merchantApplyId) =>
        EntityNotFound(merchantApplyId, "merchant apply", "商户入驻申请");

    public static T InvalidMerchantApply<T>(string merchantApplyId)
        where T : BaseResponseDto, new() =>
        Create<T>(InvalidMerchantApply(merchantApplyId));

    public static ErrorDto InvalidBusinessCircle(string businessCircleId) =>
        EntityNotFound(businessCircleId, "business circle", "商圈");

    public static T InvalidBusinessCircle<T>(string businessCircleId)
        where T : BaseResponseDto, new() =>
        Create<T>(InvalidBusinessCircle(businessCircleId));

    public static ErrorDto MerchantAlreadyOnboardedToAnotherBusinessCircle(string merchantApplyId) =>
        new()
        {
            Code = ErrorCode.MerchantAlreadyOnboardedToAnotherBusinessCircle,
            Message = $"The merchant with apply id {merchantApplyId} already onboarded to another business circle.",
            UserMessage = $"入驻申请ID为{merchantApplyId}的商户已经入驻其他商圈."
        };

    public static T MerchantAlreadyOnboardedToAnotherBusinessCircle<T>(string merchantApplyId)
        where T : BaseResponseDto, new() =>
        Create<T>(MerchantAlreadyOnboardedToAnotherBusinessCircle(merchantApplyId));

    public static ErrorDto OrderNoAlreadyLinked(string orderNo) =>
        new()
        {
            Code = ErrorCode.OrderNoAlreadyLinked,
            Message = $"The order no {orderNo} already linked to a benefits card order.",
            UserMessage = $"订单号{orderNo}已有权益卡订单绑定."
        };

    public static T OrderNoAlreadyLinked<T>(string orderNo)
        where T : BaseResponseDto, new() =>
        Create<T>(OrderNoAlreadyLinked(orderNo));

    public static ErrorDto IssuedBenefitsCardAlreadyLinked(string issuedBenefitsCardId) =>
        new()
        {
            Code = ErrorCode.IssuedBenefitsCardAlreadyLinked,
            Message = $"The issued benefits card with id {issuedBenefitsCardId} already linked to a benefits card order.",
            UserMessage = $"核发权益卡{issuedBenefitsCardId}已有订单绑定."
        };

    public static T IssuedBenefitsCardAlreadyLinked<T>(string issuedBenefitsCardId)
        where T : BaseResponseDto, new() =>
        Create<T>(IssuedBenefitsCardAlreadyLinked(issuedBenefitsCardId));

    public static ErrorDto BenefitsCardAndIssuedBenefitsCardMismatch(string benefitsCardId, string issuedBenefitsCardId) =>
        new()
        {
            Code = ErrorCode.BenefitsCardAndIssuedBenefitsCardMismatch,
            Message = $"The benefits card with id {benefitsCardId} is not linked to the issued benefits card with id {issuedBenefitsCardId}.",
            UserMessage = $"权益卡{benefitsCardId}并未与核发权益卡{issuedBenefitsCardId}绑定."
        };

    public static T BenefitsCardAndIssuedBenefitsCardMismatch<T>(string benefitsCardId, string issuedBenefitsCardId)
        where T : BaseResponseDto, new() =>
        Create<T>(BenefitsCardAndIssuedBenefitsCardMismatch(benefitsCardId, issuedBenefitsCardId));

    public static ErrorDto IssuedBenefitsCardIdAndCardNoMismatch(string issuedBenefitsCardId, string issuedBenefitsCardNo) =>
        new()
        {
            Code = ErrorCode.IssuedBenefitsCardIdAndCardNoMismatch,
            Message = $"The issued benefits card with id {issuedBenefitsCardId} is not linked to the issued benefits card no {issuedBenefitsCardNo}.",
            UserMessage = $"核发权益卡ID {issuedBenefitsCardId}与核发权益卡卡号{issuedBenefitsCardNo}不匹配."
        };

    public static T IssuedBenefitsCardIdAndCardNoMismatch<T>(string issuedBenefitsCardId, string issuedBenefitsCardNo)
        where T : BaseResponseDto, new() =>
        Create<T>(IssuedBenefitsCardIdAndCardNoMismatch(issuedBenefitsCardId, issuedBenefitsCardNo));

    public static ErrorDto IssuedBenefitsCardUserAndBuyerMismatch(string issuedBenefitsCardId) =>
        new()
        {
            Code = ErrorCode.IssuedBenefitsCardUserAndBuyerMismatch,
            Message = $"The user of issued benefits card with id {issuedBenefitsCardId} is not matching the buyer.",
            UserMessage = $"核发权益卡ID {issuedBenefitsCardId}之用户与买家不同."
        };

    public static T IssuedBenefitsCardUserAndBuyerMismatch<T>(string issuedBenefitsCardId)
        where T : BaseResponseDto, new() =>
        Create<T>(IssuedBenefitsCardUserAndBuyerMismatch(issuedBenefitsCardId));
}